/*
 * AgendaFormBakController.java
 *
 * Created on 2007��12��5��, ����11:30
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.microweb.toastmaster.webapp.action;

import com.microweb.toastmaster.Constants;
import com.microweb.toastmaster.model.Actor;
import com.microweb.toastmaster.model.Agenda;
import com.microweb.toastmaster.model.TMRole;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import com.microweb.toastmaster.model.User;
import com.microweb.toastmaster.service.ActorManager;
import com.microweb.toastmaster.service.AgendaManager;
import com.microweb.toastmaster.service.TMRoleManager;
import com.microweb.toastmaster.service.UserManager;

import java.io.Serializable;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;

public class DwrTestController extends BaseFormController {
    private final Log log = LogFactory.getLog(DwrTestController.class);
    private AgendaManager agendaManager = null;
    private TMRoleManager TMRoleManager = null;
    private UserManager userManager = null;
    private ActorManager actorManager = null;
    

    public void setAgendaManager(AgendaManager agendaManager) {
        this.agendaManager = agendaManager;
    }
    
    public void setTMRoleManager(TMRoleManager TMRoleManager) {
        this.TMRoleManager = TMRoleManager;
    }
    
    @Override
    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }
    
    public void setActorManager(ActorManager actorManager) {
        this.actorManager = actorManager;
    }
    
    public DwrTestController() {
        setCommandName("agenda");
        setCommandClass(Agenda.class);
    }

    @Override
    protected Object formBackingObject(HttpServletRequest request)
    throws Exception {
        String id = request.getParameter("id");
        Agenda agenda = null;
	log.debug("in formBackingObject ... ");
        if (!StringUtils.isEmpty(id)) {
            agenda = agendaManager.getAgenda(id);
        } else {
            agenda = new Agenda();
        }

        return agenda;
    }

    @Override
    public ModelAndView onSubmit(HttpServletRequest request,
                                 HttpServletResponse response, Object command,
                                 BindException errors)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("entering 'onSubmit' method...");
        }

        Agenda agenda = (Agenda) command;
        boolean isNew = (agenda.getId() == null);
        Locale locale = request.getLocale();

        if (request.getParameter("delete") != null) {
            agendaManager.removeAgenda(agenda.getId().toString());

            saveMessage(request, getText("agenda.deleted", locale));
	} else if (request.getParameter("mail") != null) {
	    sendRoleConfirmMail(request, agenda);
	    return new ModelAndView("redirect:editAgenda.html", "id", agenda.getId());
        } else {
	    fillRole(request, agenda);
            agendaManager.saveAgenda(agenda);

            String key = (isNew) ? "agenda.added" : "agenda.updated";
            saveMessage(request, getText(key, locale));
		
            if (!isNew) {
                return new ModelAndView("redirect:dwrtest.html", "id", agenda.getId());
            }
        }

        return new ModelAndView(getSuccessView());
    }
    
    protected void fillRole(HttpServletRequest request, Agenda agenda) throws Exception{
	Enumeration<?> parameters = request.getParameterNames();
	
	/* loop operate on request's parameters which starting with "role_" */
	while (parameters.hasMoreElements()) {
	    String rolename = (String)parameters.nextElement();
	    if (rolename.startsWith("role_")) {
		    String username = request.getParameter(rolename);
		    log.debug("handling role: " + rolename + " = '" + username + "'");
		    
		    // delete corresponding actor, for user changed the username to " ".
		    if (username.trim().length() == 0) {
			agenda.deleteActorByRolename(rolename);
			log.debug(agenda);
			continue;
		    }
                    
		    // username is input, so need to add or update corresponding actor.
		    TMRole tmrole = TMRoleManager.getTMRoleByName(rolename);
		    User user = userManager.getUserByUsername(username);
		    agenda.addOrUpdateActor(tmrole, user);
		    log.debug(agenda);
	    } 
	}
    }
    

       protected Map<String, Object> referenceData(HttpServletRequest request) throws Exception {  
	 HashMap<String, Object> referenceData = new HashMap<String, Object>();  
	 
	 String id = request.getParameter("id");
         Agenda agenda = null;
	 log.debug("in referenceData ...");
	 
         if (!StringUtils.isEmpty(id)) {
             agenda = agendaManager.getAgenda(id);
	     Set<?> actors = agenda.getActors();
	     Iterator<?> it = actors.iterator();
	     
	     while(it.hasNext()) {
		 Actor actor = (Actor)it.next();
		 referenceData.put(actor.getTMRole().getName(), 
			 actor.getUser().getUsername());
		 log.debug("put reference data: " + actor.getTMRole().getName() 
				 + "="  + actor.getUser().getUsername());
	     }
         }
	 
	 List<String> availableUsers = new ArrayList<String>();
	 List<?> users = userManager.getUsers(null);
	 for (int i=0; i<users.size(); i++) {
	     availableUsers.add(((User)users.get(i)).getUsername());
	 }
	 referenceData.put("availableUsers",availableUsers);
	 
         return referenceData;  
     }  

       
     private void sendRoleConfirmMail(HttpServletRequest request, Agenda agenda) {
	Set<?> actors = agenda.getActors();
	Locale locale = request.getLocale();
	
	// get toast master of the day
	Iterator<?> it = actors.iterator();
	User toastmaster = null;
	while(it.hasNext()) {
	    Actor actor = (Actor)it.next();
	    if(actor.getTMRole().getName().equalsIgnoreCase(Constants.ROLENAME_TOASTERMASTER)) {
		toastmaster = actor.getUser();
		break;
	    }
	}
	
	if(toastmaster == null) {
	    saveMessage(request, getText("errors.mail.no_toastmaster", locale));
	    return;
	}
       
        User loginUser = userManager.getUserByUsername(request.getRemoteUser());
        if (log.isDebugEnabled()) {
            log.debug("login user: " + loginUser);
        }
	
	// send mail to actors one by one.
	it = actors.iterator();
	String mailRecivers = "";
	DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
	String date = df.format(agenda.getDate());
	
	while(it.hasNext()) {
	    Actor actor = (Actor)it.next();
	    User user = actor.getUser();
	    String rolename = actor.getTMRole().getName();
	
	    if (log.isDebugEnabled()) {
		log.debug("sending e-mail to user [" + user.getEmail() + "]...");
	    }

	    message.setTo(user.getFullName() + "<" + user.getEmail() + ">");
            message.setFrom(loginUser.getEmail());
            message.setCc(loginUser.getEmail());
	    message.setReplyTo(loginUser.getFullName() + "<" + loginUser.getEmail() + ">");
	    message.setSubject(getText("mail.roleconfirm.subject",new Object[] {date},locale));
	    mailRecivers += "&nbsp;&lt;" + user.getFullName() + "&gt;";

	    Map<String, Serializable> model = new HashMap<String, Serializable>();
	    model.put("user", user);
	    model.put("date", date);
	    model.put("rolename",rolename);
	    model.put("toastmaster",toastmaster);
            model.put("sender", loginUser);
            model.put("venue",agenda.getVenue()==null ? " ": agenda.getVenue());
            String additionalMsg = request.getParameter("additionalMsg");
	    mailEngine.sendMessage(message, templateName, model, additionalMsg);
	}
	
	saveMessage(request, "has sent mail to: " + mailRecivers);
    }
}
